package org.wattdepot.cli.command;

import java.util.List;
import javax.xml.datatype.XMLGregorianCalendar;
import org.wattdepot.cli.processor.CommandLineInterface;
import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.util.tstamp.Tstamp;

/**
 * Power Statistic Class.
 * 
 * @author Remy Baumgarten
 * @author Kevin Chiogioji
 */
public class PowerStatistic extends CommandLineInterface implements WattDepotCliCommand {

  /**
   * Command 2.8 - Returns the maximum, minimum, or average power generated (or consumed) by the
   * source for the day. The statistic is obtained by sampling the source at the specified minute
   * intervals for the course of the day.
   * 
   * @param args -
   * @return -
   */
  public String doCommand(List<String> args) {

    String type = args.get(0);
    String source = args.get(1);
    String day = args.get(2);
    int interval;
    try {
      interval = Integer.parseInt(args.get(3));
    }
    catch (NumberFormatException nfe) {
      return "Your specified interval is not a number";
    }
    String stat = args.get(4);
    XMLGregorianCalendar startTime = null;
    XMLGregorianCalendar endTime = null;
    XMLGregorianCalendar currentInterval = null;
    Double power = null;
    Double minPower = 1000000000000000.0;
    Double maxPower = 0.0;
    Double totalPower = 0.0;
    int numberOfSamples = 0;
    try {
      // Set start and end times
      startTime = Tstamp.makeTimestamp(day);
      endTime = Tstamp.incrementDays(startTime, 1);

      // Initialize current interval to start time
      currentInterval = startTime;

      // Get data for each interval within the specified time
      while (Tstamp.lessThan(currentInterval, endTime)) {
        // Get power generated for the current interval
        if (type.equalsIgnoreCase("generated")) {
          power = client.getPowerGenerated(source, currentInterval);
        }
        // Get power consumed for the current interval
        else if (type.equalsIgnoreCase("consumed")) {
          power = client.getPowerConsumed(source, currentInterval);
        }
        // Check if current power reading is less than min
        if (power < minPower) {
          minPower = power;
        }
        // Check if current power reading is greater than max
        if (power > maxPower) {
          maxPower = power;
        }
        // Update total power read
        totalPower = totalPower + power;
        // Update interval for next reading
        currentInterval = Tstamp.incrementMinutes(currentInterval, interval);
        // Increment number of samples read
        numberOfSamples++;
      }
    }
    catch (MiscClientException mce) {
      return errorClient;
    }
    catch (BadXmlException bxe) {
      return errorXML;
    }
    catch (ResourceNotFoundException rnfe) {
      return error404;
    }
    catch (NotAuthorizedException nae) {
      return error401;
    }
    catch (Exception e) {
      return errorTimeStamp;
    }

    // If finding minimum power for interval
    if (stat.equalsIgnoreCase("min")) {
      power = minPower;
    }
    // If finding maximum power for interval
    else if (stat.equalsIgnoreCase("max")) {
      power = maxPower;
    }
    // If finding average power for interval
    else if (stat.equalsIgnoreCase("average")) {
      power = totalPower / numberOfSamples;
    }
    return Double.toString(power);
  }
}
